package com.ggs.starbug.thread;

import com.ggs.starbug.entity.TimerTask;
import com.ggs.starbug.service.ITimerTaskService;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.config.CronTask;
import org.springframework.scheduling.config.ScheduledTask;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;

import java.time.ZoneId;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Author lianghaohui
 * @Date 2021/12/24 11:57
 * @Description
 */
@Slf4j
@Component
public class TimerTaskSchedule implements SchedulingConfigurer {

    @Autowired
    private ITimerTaskService timerTaskService;

    @Autowired
    private Gson gson;

    private volatile ScheduledTaskRegistrar scheduledTaskRegistrar;

    private final ConcurrentHashMap<Long, ScheduledTask> scheduledFutures = new ConcurrentHashMap<>();

    public ScheduledTaskRegistrar getScheduledTaskRegistrar() {
        return scheduledTaskRegistrar;
    }

    public ThreadPoolTaskScheduler getThreadPoolTaskScheduler() {
        ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
        threadPoolTaskScheduler.setPoolSize(5);
        threadPoolTaskScheduler.setThreadNamePrefix("announcementsTask-");
        threadPoolTaskScheduler.setAwaitTerminationSeconds(60); //关闭线程池时，等待正在执行的任务结束最大等待时间
        threadPoolTaskScheduler.setWaitForTasksToCompleteOnShutdown(true); //用来设置线程池关闭的时候等待所有任务都完成再继续销毁其他的Bean
        threadPoolTaskScheduler.afterPropertiesSet();
        return threadPoolTaskScheduler;
    }

    public void putScheduledFutures(Long taskId, ScheduledTask scheduledTask) {
        scheduledFutures.put(taskId, scheduledTask);
    }

    public ScheduledTask addTimerTask(TimerTask timerTask) {
        ScheduledTask scheduledTask = scheduledTaskRegistrar.scheduleCronTask(new CronTask(() -> {
            log.info("{}--{}", Thread.currentThread().getName(), gson.toJson(timerTask));
        }, new CronTrigger(timerTask.getCron(), ZoneId.systemDefault())));
        putScheduledFutures(timerTask.getId(), scheduledTask);
        return scheduledTask;
    }

    public void deleteTimerTask(TimerTask timerTask) {
        ConcurrentHashMap.KeySetView<Long, ScheduledTask> keySet = scheduledFutures.keySet();
        if (keySet.contains(timerTask.getId())) {
            ScheduledTask scheduledTask = scheduledFutures.get(timerTask.getId());
            scheduledTask.cancel(); //取消定时任务
            scheduledFutures.remove(timerTask.getId());
        }
    }

    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
        this.scheduledTaskRegistrar = scheduledTaskRegistrar;
        List<TimerTask> list = timerTaskService.list();
        scheduledTaskRegistrar.setTaskScheduler(getThreadPoolTaskScheduler());
        System.out.println(gson.toJson(list));
        for (TimerTask timerTask : list) {
            ScheduledTask scheduledTask = addTimerTask(timerTask);
            putScheduledFutures(timerTask.getId(), scheduledTask);
        }
    }

}
